跳到主要内容

django 视图函数

[toc]

3.视图函数

3.1 request对象

request.path  	#request.path当前请求路径
request.method #当前请求方法(get,post...)
request.GET #获取所有get请求携带过来的数据
request.POST #获取所有post请求携带过来的数据
request.body #获取所有post请求携带过来的数据的原始格式

3.2 视图函数使用小示例

urls文件

urlpatterns = [
url(r'^admin/', admin.site.urls),
#编写一个login登陆视图文件
url(r'^login/', views.login),

]

views文件

from django.shortcuts import render,HttpResponse
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('username')
pwd = request.POST.get('password')

if uname == 'admin' and pwd == 'admin':
return HttpResponse('登陆成功!')
else:
return HttpResponse('登陆失败!!!')

html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{#<form action="">#}
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登陆">
</form>

</body>
</html>

为了验证post请求,注释settings文件中的一行

Django项目下同名目录中的settings文件,48
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

浏览器访问

login1

错误的示例

urls文件

def login(request):
if request.method == 'POST':
return render(request,'login.html')
else:
uname = request.GET.get('username')
pwd = request.GET.get('password')

if uname == 'admin' and pwd == 'admin':
return HttpResponse('登陆成功!')
else:
return HttpResponse('登陆失败!!!')

html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#<这里指定提交请求方法为post>#}
<form action="" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="登陆">
</form>

</body>
</html>

为了验证post请求,注释settings文件中的一行

Django项目下同名目录中的settings文件,48
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

按照之前的理解应该是会返回登陆界面,因为我login.html文件中form表单写的请求方法是post,而views视图文件中的逻辑判断是如果请求是post则返回登陆界面,但是实际情况并不是这样

iShot_2024-08-29_19.27.05

为什么会直接返回登陆失败呢?

原因:当浏览器打开页面的时候,默认的方法就是GET,当点击登陆那一刻才会根据form表单中的method指定的请求类型而进行转变,但是现在直接就是GET方法,因此在login函数的判断中就直接跳到了第一个else后面,但是此时根本就没有用户登陆界面出现,所以就无法获取用户名和密码,所以会直接提示登陆失败!!!

3.3 响应方法

  • render返回html页面
  • HttpResponse返回字符串
  • redirect

3.3.1render 返回html页面

views文件中的写法

#需要导入HttpResponse
from django.shortcuts import render,HttpResponse

# Create your views here.

def index(request):
return render(request,'index.html')

3.3.2 HttpResponse 返回字符串

views文件中的写法

#需要导入HttpResponse
from django.shortcuts import render,HttpResponse

# Create your views here.

#HttpResponse方法中直接写字符串
def index(request):
# return render(request,'index.html')
return HttpResponse('HttpResponse方法返回的是字符串')

iShot_2024-08-29_19.29.06

3.3.3 redirect 重定向

FBV写法

urls文件

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/', views.home),
url(r'^login/', views.login),
]

views文件

#redirect方法需要导入redirect
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.

def home(request):

return HttpResponse('登陆成功')


def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('uname')
pwd = request.POST.get('pwd')

if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')

redict是重定向,之前我们访问的时候如果登陆失败就直接提示登陆失败
现在使用了redict重定向
如果登陆成功就重定向到另一个路径下,这里是/home,也就是登陆成功页面
如果登陆失败就还是重定向到访问路径下,这里是/login,也就是登陆界面
CBV写法

urls文件

urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^login/', views.login),
url(r'^login/', views.LoginView.as_view()),
]

views文件

#redirect方法需要导入redirect
from django.shortcuts import render,HttpResponse,redirect
from django.views import View #CBV写法中需要导入View
# Create your views here.

def home(request):

return HttpResponse('登陆成功')

class LoginView(View):
def get(self,request):
return render(request, 'login.html')

def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')

if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')


redict是重定向,之前我们访问的时候如果登陆失败就直接提示登陆失败
现在使用了redict重定向
如果登陆成功就重定向到另一个路径下,这里是/home,也就是登陆成功页面
如果登陆失败就还是重定向到访问路径下,这里是/login,也就是登陆界面

3.4 CBV和FBV

3.4.1含义

  • FBV:function based view :基于函数的视图逻辑
  • CBV:class based view :基于类的视图逻辑

3.4.2 CBV

CBV中url写法

 # url(r'^login/', views.login),
url(r'^login/', views.LoginView.as_view()),

CBV中views写法

from django.shortcuts import render,HttpResponse,redirect
from django.views import View #CBV写法中需要导入View
# Create your views here.

class LoginView(View):
def get(self,request):
return render(request, 'login.html')

def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')

if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')

CBV中源码重点

    def dispatch(self, request, *args, **kwargs):  #根据请求方法去分发对应的类发放来执行
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #反射!!!!
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)

CBV中重写dispatch方法

class LoginView(View):
def dispatch(self, request, *args, **kwargs):
print(111)
# print(request.META) #http所有相关请求头信息
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print(222)
return ret
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')
def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
return redirect('/home/')
else:
return redirect('/login/')

3.4.3 FBV

FBV中url写法

url(r'^login/', views.login),
#url(r'^login/', views.LoginView.as_view()),

FBV中views写法

from django.shortcuts import render,HttpResponse,redirect
# Create your views here.

def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
uname = request.POST.get('uname')
pwd = request.POST.get('pwd')

if uname == 'admin' and pwd == 'admin':
# return HttpResponse('登陆成功')
return redirect('/home/')
else:
# return HttpResponse('登陆失败')
return redirect('/login/')

3.4.4 CBV和FBV的装饰器

def func(f):
def foo(request):
print(111)
ret = f(request)
print(222)
return ret
return foo


#FBV 模式下,和普通函数加装饰器是一样的写法
@func
def home(request):
print('home')
return HttpResponse('你懂什么是装饰器吗?')


CBV加装饰的三个姿势:
# @method_decorator(func,name='get') 位置3
class LoginView(View):
# @method_decorator(func) #位置2
def dispatch(self, request, *args, **kwargs):
print('aaaa')
ret = super().dispatch(request, *args, **kwargs) #render(request, 'login.html')
print('bbbb')
return ret
@method_decorator(func) #位置1
def get(self,request):
print('this is get method!!!')
return render(request, 'login.html')

def post(self,request):
uname = request.POST.get('username')
pwd = request.POST.get('password')
if uname == 'admin' and pwd == 'admin':
return redirect('/home/')
else:
return redirect('/login/')